<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      var arr = [
        { id: "29", pid: "", name: "总裁办" },
        { id: "2c", pid: "", name: "财务部" },
        { id: "2d", pid: "2c", name: "财务核算部" },
        { id: "2f", pid: "2c", name: "薪资管理部" },
        { id: "d2", pid: "", name: "技术部" },
        { id: "d3", pid: "d2", name: "Java研发部" },
        { id: "d31", pid: "d3", name: "Java研发部333" },
        { id: "d33", pid: "d3", name: "Java研发部333" },
      ];

      // 接受两个参数， 1：平铺数组， 2：哪种数据格式是一级菜单
      function treeToList(arr, pid) {
        function loop(pid) {
          let res = [];
          arr.forEach((item) => {
            if (item.pid === pid) {
              item.children = loop(item.id);
              res.push(item);
            }
          });
          return res;
        }

        return loop(pid);
      }

      const tree = treeToList(arr, "");

      // 转换平铺数据到tree的数据
      function transformListToTree(parms) {
        // 将所有元素的id 当做一个对象的key， 值作为对象的value
        const obj = {};

        parms.forEach((item) => {
          // 下面这句话是说将 一级菜单，都加上一个children属性，后面再里面放置二级菜单
          if (!item.pid) {
            item.children = [];
          }
          // 下面这句话是说，将数组结构转换为，对象的形式，id当做key，item值当做value
          // 构建了obj对象以后， 后面再转换数据结构的时候，方便我们去查找元素，比数组方便
          obj[item.id] = item;
        });
        // obj这个对象是方便我们去查找元素的，因为数组只能通过索引号去查找
        // arr[0] arr[3]   arr['29']
        // 我们查找的元素，不是索引号，而是字符串
        // obj['29']  obj['aaa']   obj['2c'] 对象可以查找非数字的 元素

        const newArr = [];
        // 代码里面写了2个forEach， 不能合并，每个forEach的作用不一样
        parms.forEach((item) => {
          // 首先params数组有6个元素，下面代码会执行6次
          // parent就是找到所有的 一级元素
          const parent = obj[item.pid];
          // 如果parent有值，证明当前item是 子元素，需要加到children里面去
          if (parent) {
            // 当我们在对象 .了很多次的时候
            // a.b?.c?.d?.e?.f
            // if(a.b) {
            //   a.b.c
            // } else if(a.b.c.d) {
            //   a.b.c.d.e
            // }
            parent.children?.push(item);
          } else {
            // 进入这个else，证明当前item是一级菜单
            // 直接加入到新数组里面去
            newArr.push(item);
          }
        });

        return newArr;
      }

      const ee = transformListToTree(arr);
      console.log(ee);
    </script>
  </body>
</html>
